home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
- #include <libraries/asl.h>
- #include <libraries/iff.h> /* The great IFF library */
- #include <exec/exec.h>
- #include <graphics/displayinfo.h>
- #include <intuition/intuitionbase.h>
- #if defined __SASC
- #include <proto/intuition.h>
- #include <proto/asl.h>
- #include <proto/dos.h>
- #include <proto/graphics.h>
- #include <proto/exec.h>
- #else
- #include <clib/intuition_protos.h>
- #include <clib/asl_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/exec_protos.h>
- #endif
-
- #define VERSION "1.1"
-
- /***********************************************\
- * *
- * ILBM basic definitions *
- * *
- \***********************************************/
-
- /* ILBM compression techniques */
- #define cmpNone 0
- #define cmpByteRun1 1
-
- /* ILBM masking techniques */
- #define mskNone 0
- #define mskHasMask 1
- #define mskHasTransparentColor 2
- #define mskLasso 3
-
- /***********************************************\
- * *
- * Needed for iff.library *
- * *
- \***********************************************/
-
- /* A macro */
- #define MAXPACKEDSIZE(s) ((s)*2)
-
- /* how many bytes to buffer in BODY chunk */
- #define BODYBUFSIZE 10000
-
-
- /***********************************************\
- * *
- * Constants and variables *
- * *
- \***********************************************/
-
- static char *Ver = "$VER:ScrDump " VERSION " " __AMIGADATE__ " ©1995-6 Leopold-Soft";
-
- typedef enum SAVEMODE {
- SM_WIN,
- SM_SCR
- };
-
- typedef enum ERRORCODE {
- EC_NONE,
- EC_NO_ACTIVE_WIN,
- EC_OLD_OR_NO_IFF_LIBRARY,
- EC_OLD_OS,
- EC_CANT_SAVE
- };
-
- #define SF_NOWINBORDERS (1<<0)
- #define SF_SAFE (1<<1)
-
- static char *defaultFileName = "RAM:ScrDumpFile";
-
- /***********************************************\
- * *
- * SaveScrWin saves a window or screen to the *
- * given file. *
- * *
- \***********************************************/
-
- static int SaveScrWin(struct Screen *scr, struct Window *win, char *name, ULONG flags) {
- extern struct IntuitionBase *IntuitionBase;
- extern struct ExecBase *SysBase;
- struct Library *IFFBase;
- IFFL_HANDLE iffH;
- BOOL success = FALSE;
- UBYTE *bodyBuf = NULL;
- struct IFFL_BMHD bmhd;
- UBYTE *oneLine = NULL;
- enum SAVEMODE mode = scr ? SM_SCR : SM_WIN;
- BOOL OS3 = SysBase->LibNode.lib_Version >= 39;
- struct RastPort *srcRPort;
- struct DisplayInfo myDisplayInfo;
- UBYTE *colors = NULL;
- BOOL quickSave = (!OS3 || (mode == SM_SCR &&
- GetBitMapAttr(scr->RastPort.BitMap, BMA_FLAGS)
- & BMF_STANDARD));
- LONG depth, xStart=0, yStart=0, width, height;
- int i;
- ULONG modeID, iffrowbytes;
- struct RastPort stdLineRPort1, stdLineRPort2, scrLineRPort;
- struct BitMap *stdLineBMap1=NULL, *stdLineBMap2=NULL, *scrLineBMap=NULL;
- char vStr[80];
- time_t tt;
- struct tm *t;
-
- if (!OS3 && mode == SM_WIN)
- return EC_OLD_OS;
-
- if (!(IFFBase = OpenLibrary(IFFNAME, 21L)))
- return EC_OLD_OR_NO_IFF_LIBRARY;
-
- if (name == NULL || name[0] == '\0')
- name = defaultFileName;
-
- if (mode == SM_WIN) {
- scr = win->WScreen;
- srcRPort = win->RPort;
- } else {
- srcRPort = &scr->RastPort;
- }
-
- modeID = GetVPModeID(&scr->ViewPort);
-
- if (OS3) {
- depth = GetBitMapAttr(srcRPort->BitMap, BMA_DEPTH);
- } else {
- depth = srcRPort->BitMap->Depth;
- }
-
- if (mode == SM_WIN) {
- if (flags && SF_NOWINBORDERS) {
- xStart = win->BorderLeft;
- yStart = win->BorderTop;
- width = win->Width - xStart - win->BorderRight;
- height = win->Height - yStart - win->BorderBottom;
- } else {
- width = win->Width;
- height = win->Height;
- }
- } else {
- width = scr->Width;
- height = scr->Height;
- }
-
- iffrowbytes = ((width + 15L) & ~15L) >> 3;
-
- GetDisplayInfoData(NULL, (UBYTE *) &myDisplayInfo, sizeof(struct DisplayInfo),
- DTAG_DISP, modeID);
-
- if (!(colors = malloc((1<<depth) * 3)) ||
- !(bodyBuf = malloc(BODYBUFSIZE)))
- goto error;
-
- if (!quickSave) {
- if (!(stdLineBMap1 = AllocBitMap(width+16, 1, depth, BMF_MINPLANES, NULL)) ||
- !(stdLineBMap2 = AllocBitMap(width+16, 1, depth, BMF_MINPLANES, NULL)) ||
- !(scrLineBMap = AllocBitMap(scr->Width, 1, depth, BMF_MINPLANES, srcRPort->BitMap)) ||
- !(oneLine = malloc((iffrowbytes<<3) + 16)))
- goto error;
-
- InitRastPort(&stdLineRPort1);
- stdLineRPort1.BitMap = stdLineBMap1;
- InitRastPort(&stdLineRPort2);
- stdLineRPort2.BitMap = stdLineBMap2;
- scrLineRPort = *srcRPort;
- scrLineRPort.Layer = NULL;
- scrLineRPort.BitMap = scrLineBMap;
- }
-
- iffH = IFFL_OpenIFF(name, IFFL_MODE_WRITE);
-
- if (iffH) {
- /*
- Let's write the BMHD chunk
- */
-
- bmhd.w = width;
- bmhd.h = height;
- bmhd.x = xStart;
- bmhd.y = yStart;
- bmhd.nPlanes = depth;
- bmhd.masking = mskNone;
- bmhd.compression = cmpByteRun1;
- bmhd.pad1 = 0;
- bmhd.transparentColor = 0;
- bmhd.xAspect = myDisplayInfo.Resolution.y;
- bmhd.yAspect = myDisplayInfo.Resolution.x;
- bmhd.pageWidth = bmhd.w;
- bmhd.pageHeight = bmhd.h;
- success = IFFL_PushChunk(iffH, ID_ILBM, ID_BMHD);
- if (success) success = IFFL_WriteChunkBytes(iffH, &bmhd, sizeof(bmhd));
- if (success) success = IFFL_PopChunk(iffH);
-
-
- /*
- Let's write the CMAP chunk
- */
- if (success) success = IFFL_PushChunk(iffH, ID_ILBM, ID_CMAP);
- for (i=0; i<(1<<depth); i++) {
- ULONG tmpCol[3];
-
- if (OS3) {
- GetRGB32(scr->ViewPort.ColorMap, (ULONG)i, 1, tmpCol);
- colors[i*3+0] = tmpCol[0] >> 24;
- colors[i*3+1] = tmpCol[1] >> 24;
- colors[i*3+2] = tmpCol[2] >> 24;
- } else {
- tmpCol[0] = GetRGB4(scr->ViewPort.ColorMap, (ULONG)i);
- colors[i*3+0] = ((tmpCol[0] ) >> 8) * 0x11;
- colors[i*3+1] = ((tmpCol[0] & 0x0F0 ) >> 4) * 0x11;
- colors[i*3+2] = ((tmpCol[0] & 0x00F ) ) * 0x11;
- }
- }
- if (success) success = IFFL_WriteChunkBytes(iffH, colors, (LONG)(1<<depth)*3);
- if (success) success = IFFL_PopChunk(iffH);
-
-
- /*
- Let's write a CAMG chunk
- */
- if (success) success = IFFL_PushChunk(iffH, ID_ILBM, ID_CAMG);
- if (success) success = IFFL_WriteChunkBytes(iffH, &modeID, sizeof(modeID));
- if (success) success = IFFL_PopChunk(iffH);
-
- /*
- Let's write an ANNO chunk
- */
- time(&tt);
- t = localtime(&tt);
- strcpy(vStr, "$VER: Written by ScrDump " VERSION " (");
- i = strlen(vStr);
- t->tm_mon++;
- vStr[i++] = '0' + t->tm_mday/10;
- vStr[i++] = '0' + t->tm_mday%10;
- vStr[i++] = '.';
- vStr[i++] = '0' + t->tm_mon/10;
- vStr[i++] = '0' + t->tm_mon%10;
- vStr[i++] = '.';
- vStr[i++] = '0' + (t->tm_year%100)/10;
- vStr[i++] = '0' + t->tm_year%10;
- strcpy(vStr + i, ") ©1995-6 Leopold-Soft");
-
- /* sprintf(vStr, "%02d.%02d.%02d) ©1995-6 Leopold-Soft",
- t->tm_mday, t->tm_mon, t->tm_year % 100);
- */
- if (success) success = IFFL_PushChunk(iffH, ID_ILBM, ID_ANNO);
- if (success) success = IFFL_WriteChunkBytes(iffH, vStr, strlen(vStr)+1);
- if (success) success = IFFL_PopChunk(iffH);
-
- /*
- Let's write a BODY chunk
- */
- if (success) {
- int row, iplane, bodysize=0;
- int rowOffset = -srcRPort->BitMap->BytesPerRow;
-
- success = IFFL_PushChunk(iffH, ID_ILBM, ID_BODY);
-
- for (row=0; row < bmhd.h; ++row) {
- if (!quickSave) {
- int i;
- ReadPixelLine8( srcRPort, xStart, row+yStart, width, oneLine, &scrLineRPort);
- for (i=0; i<16; i++)
- oneLine[width+i] = 0;
- WritePixelLine8(&stdLineRPort1, 0, 0, width+16, oneLine, &stdLineRPort2);
- } else {
- rowOffset += srcRPort->BitMap->BytesPerRow;
- }
- for (iplane=0; iplane < depth; ++iplane) {
- int comprsize;
-
- /* Flush buffer if full */
- if (bodysize > (BODYBUFSIZE-MAXPACKEDSIZE(iffrowbytes))) {
- if (success) {
- success = IFFL_WriteChunkBytes(iffH, bodyBuf, bodysize);
- bodysize = 0;
- }
- }
-
- /* Compress one row */
- if (success) {
- if (!quickSave) {
- success = comprsize = IFFL_CompressBlock(
- stdLineRPort1.BitMap->Planes[iplane],
- bodyBuf+bodysize, iffrowbytes, IFFL_COMPR_BYTERUN1);
- } else {
- success = comprsize = IFFL_CompressBlock(
- srcRPort->BitMap->Planes[iplane] + rowOffset,
- bodyBuf+bodysize, iffrowbytes, IFFL_COMPR_BYTERUN1);
- }
- bodysize += comprsize;
- }
- }
- }
-
- /* Flush the rest of body */
- if (bodysize && success)
- success = IFFL_WriteChunkBytes(iffH, bodyBuf, bodysize);
-
- if (success) success = IFFL_PopChunk(iffH);
- }
- IFFL_CloseIFF(iffH);
- }
-
- error:
- if (oneLine) free(oneLine);
- if (scrLineBMap) FreeBitMap(scrLineBMap);
- if (stdLineBMap2) FreeBitMap(stdLineBMap2);
- if (stdLineBMap1) FreeBitMap(stdLineBMap1);
- if (bodyBuf) free(bodyBuf);
- if (colors) free(colors);
-
- CloseLibrary(IFFBase);
-
- return success ? EC_NONE : EC_CANT_SAVE;
- }
-
-
-
- static int SaveScreen(struct Screen *scr, char *name, ULONG flags) {
- return SaveScrWin(scr, NULL, name, flags);
- }
-
-
-
- static int SaveWindow(struct Window *win, char *name, ULONG flags) {
- return SaveScrWin(NULL, win, name, flags);
- }
-
-
-
- /***********************************************\
- * *
- * The main program *
- * *
- \***********************************************/
-
- int main(int argc, char **argv) {
- int errorcode = EXIT_SUCCESS;
- int i;
- enum SAVEMODE savemode = SM_SCR;
- ULONG flags = 0;
- char *fileName = defaultFileName;
-
- for (i = 1; i < argc; i++) {
- if (!strcmp(argv[i], "-w")) {
- savemode = SM_WIN;
- } else if (!strcmp(argv[i], "-s")) {
- savemode = SM_SCR;
- } else if (!strcmp(argv[i], "-b")) {
- flags |= SF_NOWINBORDERS;
- } else if (!strcmp(argv[i], "-B")) {
- flags &= ~SF_NOWINBORDERS;
- } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "?")) {
- Printf("\nScreen Dump v" VERSION " ©1995-6 Leopold-Soft\n"
- "Usage: %s [-w] [-s] [-b] [-B] [-h|?] [filnam]\n"
- "-w\tSave active window (requires OS3)\n"
- "-s\tSave uppermost screen (default)\n"
- "-b\tDon't save window borders\n"
- "-B\tSave window borders (default)\n"
- "-h|?\tShow this help\n"
- "filnam\tSpecify file name to save to (default: %s)\n\n"
- , argv[0], defaultFileName);
- return EXIT_SUCCESS;
- } else {
- fileName = argv[i];
- }
- }
-
- Delay(500);
-
- switch(savemode) {
- case SM_SCR:
- errorcode = SaveScreen(IntuitionBase->FirstScreen, fileName, flags);
- DisplayBeep(IntuitionBase->FirstScreen);
- break;
- case SM_WIN:
- if (!IntuitionBase->ActiveWindow) {
- errorcode = EC_NO_ACTIVE_WIN;
- } else {
- errorcode = SaveWindow(IntuitionBase->ActiveWindow, fileName, flags);
- DisplayBeep(IntuitionBase->ActiveWindow->WScreen);
- }
- break;
- }
-
- switch (errorcode) {
- case EC_NONE:
- Printf("%s: Saved to \"%s\", ok!\n", argv[0], fileName);
- break;
- case EC_NO_ACTIVE_WIN:
- Printf("%s: Error: no active window!\n", argv[0]);
- errorcode = EXIT_FAILURE;
- break;
- case EC_OLD_OR_NO_IFF_LIBRARY:
- Printf("%s: Error: iff.library v21 or newer required!\n", argv[0]);
- errorcode = EXIT_FAILURE;
- break;
- case EC_OLD_OS:
- Printf("%s: Error: Can't save windows under OS2.x!\n", argv[0]);
- errorcode = EXIT_FAILURE;
- break;
- default:
- Printf("%s: Error: can't save to \"%s\"!\n", argv[0], fileName);
- errorcode = EXIT_FAILURE;
- break;
- }
- return errorcode;
- }
-